
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.UI;

using Swaf.Container;

namespace Swaf.Gui.AspNet2
{
	public class BizProcCoordinator : IBizProcCoordinator
	{
		protected Page m_page;
		protected ViewOfflineState m_pageState;
		protected Dictionary<string, ActiveBizProc> m_activeBizProcs = new Dictionary<string, ActiveBizProc>();
		protected Dictionary<string, ActiveWidget> m_activeWidgets = new Dictionary<string, ActiveWidget>();
		protected IMessanger m_messanger;

		public BizProcCoordinator(Page page, ViewOfflineState pageState)
		{
			m_page = page;
			m_pageState = pageState;
			Messenger.clearAll();
		}

		public IBasicView HostView { get { return m_page as IBasicView; } }
		public ViewOfflineState PageState { get { return m_pageState; } }

		public virtual IMessanger Messenger
		{
			get
			{
				m_messanger = Swaf.Application.currentApp.sessionData["Messanger"] as IMessanger;
				if(m_messanger == null)
					Swaf.Application.currentApp.sessionData["Messanger"] = m_messanger = new AspNetMessanger();
				return m_messanger;
			}
		}


		public ActiveBizProc getActiveBizProc(string bizProcId)
		{
			ActiveBizProc proc = null;
			if (!m_activeBizProcs.TryGetValue(bizProcId, out proc))
			{
				BizProcOfflineState procState = getBizProcOfflineState(bizProcId);
				if (procState != null)
					m_activeBizProcs.Add(bizProcId, proc = new ActiveBizProc(this, procState));
			}
			return proc;
		}

		public ActiveWidget getActiveWidget(string widgetId)
		{
			ActiveWidget widget = null;
			if (!m_activeWidgets.TryGetValue(widgetId, out widget))
			{
				WidgetOfflineState widgetState = getWidgetOfflineState(widgetId);
				if (widgetState != null)
				{
					//This if statement is a hack.  This is to protect a child iframe from creating widgets
					//in its page that are actually from the parent page.  this happens in the file upload page only
					//as of now.  Later there should be a more formalized way to have iframe bizprocs communicate
					//with bizprocs from the parent without the controls from the parent page being created in this iframe(s).
					if (m_page != null && !m_page.GetType().Name.EndsWith("child_aspx")  &&
						!m_page.GetType().Name.EndsWith("childpopup_aspx"))
					{
						widget = new ActiveWidget(this, widgetState);
						m_activeWidgets[widgetId] = widget;
					}
				}
			}
			return widget;
		}

		public void defineActiveWidget(ActiveWidget widget)
		{
			m_activeWidgets[widget.State.Id] = widget;
		}

		public WidgetOfflineState getWidgetOfflineState(string widgetId)
		{
			WidgetOfflineState state = null;
			m_pageState.WidgetStates.TryGetValue(widgetId, out state);
			return state;
		}

		public WidgetOfflineState addWidgetOfflineState(WidgetOfflineState state)
		{
			m_pageState.WidgetStates.Add(state.Id, state);
			return state;
		}
		
		public object getDataValueFromHostEnvironment(string dataId, ActiveBizProc bizProc)
		{
			object val = null;
			try { val = m_page.Request[bizProc.OfflineState.Id + dataId]; }
			catch { } //This is done because sometimes this will get called in the Unload event and then Request is
					  //no longer available at that point.
			return val;
		}

		public BizProcOfflineState getBizProcOfflineState(string bizProcId)
		{
			BizProcOfflineState procState = null;
			m_pageState.BizProcStates.TryGetValue(bizProcId, out procState);
			return procState;
		}

		public BizProcOfflineState addBizProcOfflineState(BizProcOfflineState state)
		{
			Debug.Assert(state != null);
			m_pageState.BizProcStates.Add(state.Id, state);
			return state;
		}

		public void removeActiveBizProc(string bizProcId)
		{
			if(m_activeBizProcs.ContainsKey(bizProcId))
				m_activeBizProcs.Remove(bizProcId);
		}

		public void removeBizProcOfflineState(string bizProcId)
		{
			m_pageState.BizProcStates.Remove(bizProcId);
		}

		static Regex s_actionRegex = new Regex(@"([^\.,]+)\.([^\(,]+)(\(([^\)]+)\))?");
		public IAction getBizProcAction(string actionId, ref object p)
		{
			IAction a = null;
			Match m = s_actionRegex.Match(actionId);
			p = null;
			if (m.Success)
			{
				ActiveBizProc proc = getActiveBizProc(m.Groups[1].Value);
				if (proc != null)
					a = proc.BizProc.Actions[m.Groups[2].Value];
				if (m.Groups.Count > 4 && !(Cmn.IsEmpty(m.Groups[4].Value)))
					p = m.Groups[4].Value;
			}
			return a;
		}

		public List<IAction> getBizProcActions(string actionIds)
		{
			List<IAction> al = new List<IAction>();
			if (actionIds != null)
			{
				string[] bizprocids = actionIds.Split(',');
				object p = null;
				foreach (string bizprocid in bizprocids)
				{
					IAction a = getBizProcAction(bizprocid, ref p);
					if (a != null)
						al.Add(a);
				}
			}
			return al;
		}

		public List<ActiveBizProc> getDependentBizProcs(string bizProcId)
		{
			List<ActiveBizProc> dependants = null;
			foreach(BizProcOfflineState procState in m_pageState.BizProcStates.Values)
				foreach(ParentBizProcInfo parentInfo in procState.ParentBizProcs.Values)
					if (bizProcId == parentInfo.ParentId || (parentInfo.ParentId == "_all" && procState.Id != bizProcId))
					{
						if (dependants == null)
							dependants = new List<ActiveBizProc>();
						dependants.Add(getActiveBizProc(procState.Id));
						break;
					}
			return dependants;
		}

		public Dictionary<string, ActiveBizProc> ActiveBizProcs { get { return m_activeBizProcs; } }
		public Dictionary<string, ActiveWidget> ActiveWidgets { get { return m_activeWidgets; } }
	}

	public class AspNetMessanger : IMessanger
	{
		protected List<UserMessage> m_activeUserMessages = new List<UserMessage>();
		public List<UserMessage> ActiveUserMessages { get { return m_activeUserMessages; } }

		public void add(string msgId, INameAddressSupport replacements)
		{
			m_activeUserMessages.Add(new UserMessage(msgId, replacements));
		}

		public void addRange(List<UserMessage> msgs)
		{
			m_activeUserMessages.AddRange(msgs);
		}

		public void clearAll() { m_activeUserMessages.Clear(); }
	}
}
